﻿using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Collections.Generic;
using System.Text;
using ELMApplication.Web.DataModel;
using System.Configuration;
using System.Xml.Linq;
using System.Data;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections;

namespace ELMApplication.Web
{
    [ServiceContract(Namespace = "ELMService")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class ELMService
    {
        private ELMEntities ObjectContext = new ELMEntities(ConfigurationManager.ConnectionStrings["ELMEntities"].ConnectionString);

        [OperationContract]
        public Human GetT_HummanByAccount(string Uname, string PWD)
        {
            Human hm = null;
            var query = (from q in this.ObjectContext.t_Human.Include("t_Duty")
                         where q.Human_ID == Uname && q.Password == PWD
                         select q).ToList();
            if (query.Count == 1)
            {
                hm = query.First().ConvertToHuman(ObjectContext);
            }
            return hm;

        }
        [OperationContract]
        public Human GetT_HummanByUid(string UId)
        {
            Human hm = null;
            var query = (from q in this.ObjectContext.t_Human.Include("t_Duty")
                         where q.Human_ID == UId
                         select q).ToList();
            if (query.Count == 1)
            {
                hm = query.First().ConvertToHuman(ObjectContext);
            }
            return hm;

        }
        [OperationContract]
        public List<TaskData> GetTastDataWhichUserUnreaded(string Uid)
        {
            List<TaskData> ds = new List<TaskData>();
            var list = (from q in this.ObjectContext.t_DataflowDetail.Include("t_Dataflow")
                        where q.Recieve_User_Id == Uid && !q.Task_Received_Flag
                        select q).ToList();

            foreach (var item in list)
            {
                TaskData dr = new TaskData()
                {
                    ID = item.ID,
                    TaskId = item.t_Dataflow.Task_ID,
                    TaskName = item.t_Dataflow.Task_Name,
                    TaskStartDate = item.t_Dataflow.Task_CreateTime,
                    Sender = ObjectContext.t_Human.Include("t_Duty").First(c => c.Human_ID == item.Create_User_Id).ConvertToHuman(ObjectContext),
                    Reciever = ObjectContext.t_Human.Include("t_Duty").First(c => c.Human_ID == item.Recieve_User_Id).ConvertToHuman(ObjectContext),
                };
                ds.Add(dr);
            }
            return ds;
        }
        [OperationContract]
        public List<TaskData> GetTastDataWhichUserReaded(string Uid)
        {
            List<TaskData> ds = new List<TaskData>();
            var list = (from q in this.ObjectContext.t_DataflowDetail.Include("t_Dataflow")
                        where q.Recieve_User_Id == Uid && q.Task_Received_Flag
                        select q).ToList();

            foreach (var item in list)
            {
                TaskData dr = new TaskData()
                {
                    ID = item.ID,
                    TaskId = item.t_Dataflow.Task_ID,
                    TaskName = item.t_Dataflow.Task_Name,
                    TaskStartDate = item.t_Dataflow.Task_CreateTime,
                    Sender = ObjectContext.t_Human.Include("t_Duty").First(c => c.Human_ID == item.Create_User_Id).ConvertToHuman(ObjectContext),
                    Reciever = ObjectContext.t_Human.Include("t_Duty").First(c => c.Human_ID == item.Recieve_User_Id).ConvertToHuman(ObjectContext),
                };
                ds.Add(dr);
            }
            return ds;
        }
        [OperationContract]
        public List<TaskData> GetTastDataWhichUserSended(string Uid)
        {
            List<TaskData> ds = new List<TaskData>();
            var list = (from q in this.ObjectContext.t_DataflowDetail.Include("t_Dataflow")
                        where q.Create_User_Id == Uid
                        select q).ToList();

            foreach (var item in list)
            {
                TaskData dr = new TaskData()
                {
                    ID = item.ID,
                    TaskId = item.t_Dataflow.Task_ID,
                    TaskName = item.t_Dataflow.Task_Name,
                    TaskStartDate = item.t_Dataflow.Task_CreateTime,
                    Sender = ObjectContext.t_Human.Include("t_Duty").First(c => c.Human_ID == item.Create_User_Id).ConvertToHuman(ObjectContext),
                    Reciever = ObjectContext.t_Human.Include("t_Duty").First(c => c.Human_ID == item.Recieve_User_Id).ConvertToHuman(ObjectContext),
                };
                ds.Add(dr);
            }
            return ds;
        }
        [OperationContract]
        public List<Matter> GetMatters()
        {
            List<Matter> ds = new List<Matter>();
            var query = from q in this.ObjectContext.t_Matter select q;
            foreach (var item in query)
            {
                ds.Add(item.ConvertToMatter(ObjectContext));
            }

            return ds;

        }
        [OperationContract]
        public Matter GetMatterById(string id)
        {
            
            var query = (from q in this.ObjectContext.t_Matter where q.Matter_ID==id select q).ToList();
            if (query.Count == 1)
            {
                return query.First().ConvertToMatter(ObjectContext);
            }
            else
                return null;

        }

        [OperationContract]
        public Dataflow GetDataflowByTaskDetailId(int taskDetailId, string uid)
        {
            Dataflow df = null;
            var query = (from q in ObjectContext.t_DataflowDetail.Include("t_Dataflow").Include("Attachment")
                         where q.ID == taskDetailId
                         select q).ToList();

            if (query.Count == 1)
            {
                var data = query.First();
                var matter = ObjectContext.t_Matter.First(c => c.Matter_ID == data.t_Dataflow.Object_ID);
               
                Matter mt = matter.ConvertToMatter(ObjectContext);
               
                var sd = ObjectContext.t_Human.Include("t_Duty").First(c => c.Human_ID == data.Create_User_Id);
                Human sender = sd.ConvertToHuman(ObjectContext);
                var rc = ObjectContext.t_Human.Include("t_Duty").First(c => c.Human_ID == data.Recieve_User_Id);
                Human reciever = rc.ConvertToHuman(ObjectContext);
                var inx = (from q in data.t_Dataflow.t_DataflowDetail
                           where q.Create_User_Id == uid
                           select q).ToList();


                df = new Dataflow()
                {
                    CreateDate = data.t_Dataflow.Task_CreateTime,
                    FinishDate = data.RecievedDate,
                    InfoClass = "",
                    MaxIndex = 0,
                    OutflowId = data.Sub_Task_Index.ToString(),
                    OutStatus = data.Task_Received_Flag.ToString(),
                    Quantity = data.t_Dataflow.Object_Amount,
                    StartDate = data.CreateDate,
                    SubTaskContent = data.Sub_Task_Content,
                    SubTaskId = data.Sub_Task_ID,
                    SubTaskName = data.Sub_Task_Name,
                    TaskID = data.t_Dataflow.Task_ID,
                    UnitName = data.t_Dataflow.Unit,
                    Matter = mt,
                    SenderUser = sender,
                    ReceiveUser = reciever,
                    CurrentOutMSGMaxIndex = inx.Count + 1,
                    Attachments = new List<ELMApplication.Web.DataModel.Attachment>()
                };
                var atts = (from q in data.Attachment

                            select q).ToList();
                foreach (var item in atts)
                {
                    df.Attachments.Add(item.ConvertToAttachment());
                }
            }
            return df;
        }
        [OperationContract]
        public Dataflow GetDataflowWithAllHumanByTaskIdAndUid(int taskDetailId, string uId)
        {
            var df = GetDataflowByTaskDetailId(taskDetailId, uId);
            df.AllHuman = GetAllHuman();
            return df;

        }
        [OperationContract]
        private List<Human> GetAllHuman()
        {
            List<Human> ds = new List<Human>();
            foreach (var item in ObjectContext.t_Human.Include("t_Duty").ToList())
            {
                ds.Add(item.ConvertToHuman(ObjectContext));
            }
            return ds;
        }

        [OperationContract]
        public int InsertDataflowDetail(Dataflow df)
        {
            int bl = 0;
            if (ObjectContext.t_Dataflow.Any(c => c.Task_ID == df.TaskID))
            {
                var task = ObjectContext.t_Dataflow.Include("t_DataflowDetail").First(c => c.Task_ID == df.TaskID);
                int count = (from q in task.t_DataflowDetail
                             select q).Count();
                t_DataflowDetail data = new t_DataflowDetail()
                {
                    Create_User_Id = df.SenderUser.HumanId,
                    CreateDate = df.StartDate,
                    Recieve_User_Id = df.ReceiveUser.HumanId,
                    RecievedDate = df.FinishDate,
                    Sub_Task_Content = df.SubTaskContent,
                    Sub_Task_ID = df.SubTaskId,
                    Sub_Task_Name = df.SubTaskName,
                    Task_Received_Flag = df.FinishDate.HasValue ? true : false,
                    Sub_Task_Index = count + 1,


                };
                task.t_DataflowDetail.Add(data);
                ObjectContext.SaveChanges();
                bl = data.ID;
            }
            return bl;

        }

        static Dictionary<string, byte[]> FileMemoryDic = new Dictionary<string, byte[]>();
        [OperationContract]
        public void StoreAttachment(int detailId, Guid mailGuid, string fileName, byte[] data, bool firstChunk, bool lastChunk)
        {

            if (firstChunk)
            {
                FileMemoryDic.Add(mailGuid.ToString() + fileName, data);
            }
            else
            {
                byte[] newdata = new byte[FileMemoryDic[mailGuid.ToString() + fileName].Length + data.Length];
                FileMemoryDic[mailGuid.ToString() + fileName].CopyTo(newdata, 0);
                data.CopyTo(newdata, FileMemoryDic[mailGuid.ToString() + fileName].Length);
                FileMemoryDic[mailGuid.ToString() + fileName] = newdata;


            }
            if (lastChunk)
            {
                string[] arr = fileName.Split('.');
                var Datadetail = ObjectContext.t_DataflowDetail.First(c => c.ID == detailId);

                Attachment at = new Attachment()
                {
                    MailGuid = mailGuid,
                    FileData = FileMemoryDic[mailGuid.ToString() + fileName],
                    FileName = fileName,

                    Type = arr.Last()
                };
                Datadetail.Attachment.Add(at);

                ObjectContext.SaveChanges();
                FileMemoryDic.Remove(mailGuid.ToString() + fileName);
            }
        }
        [OperationContract]
        public void StoreResource(Guid resourceId, string fileName, byte[] data, bool firstChunk, bool lastChunk)
        {

            if (firstChunk)
            {
                if (FileMemoryDic.Any(c => c.Key == resourceId.ToString() + fileName))
                {
                    FileMemoryDic.Remove(resourceId.ToString() + fileName);
                }
                FileMemoryDic.Add(resourceId.ToString() + fileName, data);
            }
            else
            {
                byte[] newdata = new byte[FileMemoryDic[resourceId.ToString() + fileName].Length + data.Length];
                FileMemoryDic[resourceId.ToString() + fileName].CopyTo(newdata, 0);
                data.CopyTo(newdata, FileMemoryDic[resourceId.ToString() + fileName].Length);
                FileMemoryDic[resourceId.ToString() + fileName] = newdata;


            }
            if (lastChunk)
            {
                string[] arr = fileName.Split('.');
                var resource = (from q in ObjectContext.t_Resource where q.ResourceId == resourceId select q).ToList();
                if (resource.Count == 0)
                {
                    t_Resource at = new t_Resource()
                    {
                        ResourceId = resourceId,
                        FileData = FileMemoryDic[resourceId.ToString() + fileName],
                        FileName = fileName,
                        Type = arr.Last()
                    };
                    ObjectContext.AddTot_Resource(at);

                }
                else
                {
                    resource.First().FileData = FileMemoryDic[resourceId.ToString() + fileName];
                }
                ObjectContext.SaveChanges();
                FileMemoryDic.Remove(resourceId.ToString() + fileName);
            }
        }

        [OperationContract]
        public string GetMainTaskId(string uid)
        {
            var query = from q in ObjectContext.t_Dataflow
                        where q.Task_Start_UserId == uid
                        select q;
            return uid + "-" + (query.Count() + 1).ToString();
        }

        [OperationContract]
        public int SendNewData(Dataflow df)
        {
            int bl = 0;
            if (!ObjectContext.t_Dataflow.Any(c => c.Task_ID == df.TaskID))
            {
                t_Dataflow td = new t_Dataflow()
                {
                    Object_Amount = df.Quantity,
                    Object_ID = df.Matter.MatterId,
                    Object_Name = df.Matter.MatterName,
                    Task_CreateTime = df.CreateDate,
                    Task_ID = df.TaskID,
                    Task_Name = df.SubTaskName,
                    Task_Start_UserId = df.SenderUser.HumanId,
                    Unit = df.UnitName,

                };

                t_DataflowDetail data = new t_DataflowDetail()
                {
                    Create_User_Id = df.SenderUser.HumanId,
                    CreateDate = df.StartDate,
                    Recieve_User_Id = df.ReceiveUser.HumanId,
                    RecievedDate = df.FinishDate,
                    Sub_Task_Content = df.SubTaskContent,
                    Sub_Task_ID = df.SubTaskId,
                    Sub_Task_Name = df.SubTaskName,
                    Task_Received_Flag = df.FinishDate.HasValue ? true : false,
                    Sub_Task_Index = 1,


                };
                td.t_DataflowDetail.Add(data);
                ObjectContext.AddTot_Dataflow(td);
                ObjectContext.SaveChanges();
                bl = data.ID;
            }
            return bl;
        }

        [OperationContract]
        public List<Dataflow> GetAllDataflowDetials(string taskID)
        {
            List<Dataflow> ds = new List<Dataflow>();
            var query = (from q in ObjectContext.t_Dataflow.Include("t_DataflowDetail")
                         where q.Task_ID == taskID
                         select q).ToList();
            if (query.Count == 1)
            {
                foreach (var data in query.First().t_DataflowDetail.OrderBy(c => c.Sub_Task_Index))
                {
                    var sd = ObjectContext.t_Human.Include("t_Duty").First(c => c.Human_ID == data.Create_User_Id);
                    Human sender = new Human()
                    {
                        DutyId = sd.t_Duty.DutyId,
                        HumanDuty = sd.t_Duty.DutyName,
                        HumanId = sd.Human_ID,
                        HumanName = sd.Human_Name
                    };
                    var rc = ObjectContext.t_Human.Include("t_Duty").First(c => c.Human_ID == data.Recieve_User_Id);
                    Human reciever = new Human()
                    {
                        DutyId = rc.t_Duty.DutyId,
                        HumanDuty = rc.t_Duty.DutyName,
                        HumanId = rc.Human_ID,
                        HumanName = rc.Human_Name
                    };
                    Dataflow df = new Dataflow()
                    {
                        CreateDate = query.First().Task_CreateTime,
                        FinishDate = data.RecievedDate,
                        InfoClass = "",
                        MaxIndex = 0,
                        OutflowId = data.Sub_Task_Index.ToString(),
                        OutStatus = data.Task_Received_Flag.ToString(),
                        Quantity = query.First().Object_Amount,
                        StartDate = data.CreateDate,
                        SubTaskContent = data.Sub_Task_Content,
                        SubTaskId = data.Sub_Task_ID,
                        SubTaskName = data.Sub_Task_Name,
                        TaskID = query.First().Task_ID,
                        UnitName = query.First().Unit,

                        SenderUser = sender,
                        ReceiveUser = reciever,
                    };
                    ds.Add(df);

                }
            }
            return ds;
        }

        [OperationContract]
        public void SetIsReaded(int detailId)
        {
            if (ObjectContext.t_DataflowDetail.Any(c => c.ID == detailId))
            {
                var detail = ObjectContext.t_DataflowDetail.First(c => c.ID == detailId);
                detail.RecievedDate = DateTime.Now;
                detail.Task_Received_Flag = true;
                ObjectContext.SaveChanges();
            }
        }

        [OperationContract]
        public List<t_Duty> GetAllDuty()
        {
            return ObjectContext.t_Duty.ToList();
        }
        [OperationContract]
        public bool AddNewUser(Human hm)
        {
            bool bl = false;
            if (!ObjectContext.t_Human.Any(c => c.Human_ID == hm.HumanId))
            {
                t_Duty td = ObjectContext.t_Duty.First(c => c.DutyId == hm.DutyId);
                t_Human th = new t_Human()
                {
                    Human_ID = hm.HumanId,
                    Human_Name = hm.HumanName,
                    t_Duty = td,
                    Password = hm.Password,
                    Attribute = hm.Attributes.ConvertToXMLDocumentOnlyValue(),

                };
                ObjectContext.AddTot_Human(th);
                ObjectContext.SaveChanges();
                bl = true;
            }
            return bl;
        }
        [OperationContract]
        public bool AddNewMatter(Matter mt)
        {
            bool bl = false;
            if (!ObjectContext.t_Matter.Any(c => c.Matter_ID == mt.MatterId))
            {
                t_Matter m = new t_Matter()
                {
                    Matter_ID = mt.MatterId,
                    Matter_Name = mt.MatterName,
                    Attribute = mt.Attributes.ConvertToXMLDocumentOnlyValue(),
                };
                ObjectContext.AddTot_Matter(m);
                ObjectContext.SaveChanges();
                bl = true;
            }
            return bl;
        }

        [OperationContract]
        public List<ELMField> GetAllField()
        {
            return (from q in ObjectContext.t_Field.Include("t_FieldGroup").Include("t_FieldType") where q.IsDeleted == false select q).ConvertToFieldTypeList();
        }
        [OperationContract]
        public List<ELMField> GetAllFieldContainsDeleted()
        {
            return (from q in ObjectContext.t_Field.Include("t_FieldGroup").Include("t_FieldType") select q).ConvertToFieldTypeList();
        }
        [OperationContract]
        public bool CheckFieldNameIsExst(string name)
        {
            return ObjectContext.t_Field.Any(c => c.FieldName == name && !c.IsDeleted);
        }
        [OperationContract]
        public void AddField(string name, int groupid, string typeid)
        {
            if (!ObjectContext.t_Field.Any(c => c.FieldName == name))
            {
                var group = ObjectContext.t_FieldGroup.First(c => c.FieldGroupId == groupid);
                var ftype = ObjectContext.t_FieldType.First(c => c.FieldTypeId == typeid);
                ObjectContext.AddTot_Field(new t_Field() { FieldId = Guid.NewGuid(), FieldName = name, IsDeleted = false, t_FieldGroup = group, t_FieldType = ftype });
            }
            else if (ObjectContext.t_Field.Any(c => c.FieldName == name && c.IsDeleted == true))
            {
                SetFieldStatus(ObjectContext.t_Field.First(c => c.FieldName == name).FieldId, false);
            }
            ObjectContext.SaveChanges();
        }
        [OperationContract]
        public void SetFieldStatus(Guid fieldId, bool isDeleted)
        {
            if (ObjectContext.t_Field.Any(c => c.FieldId == fieldId))
            {
                var field = ObjectContext.t_Field.First(c => c.FieldId == fieldId);
                field.IsDeleted = isDeleted;

            }
            ObjectContext.SaveChanges();
        }

        [OperationContract]
        public List<ContentType> GetAllContentType()
        {
            List<ContentType> ds = new List<ContentType>();

            var datas = from q in ObjectContext.t_ContentType select q;
            foreach (var data in datas)
            {
                ContentType type = new ContentType()
                {
                    ContentId = data.ContentTypeId,
                    ContentName = data.ContentTypeName,
                    Fields = new Dictionary<ELMField, string>()
                };
                type.Fields = data.ContentFields.ConvertXmlToFieldsWithTemplateAttribute(ObjectContext);
                ds.Add(type);
            }
            return ds;
        }

        [OperationContract]
        public ContentType GetContentTypeById(Guid Id)
        {
            var datas = (from q in ObjectContext.t_ContentType where q.ContentTypeId == Id select q).ToList();
            if (datas.Count() == 1)
            {
                ContentType type = new ContentType()
                {
                    ContentId = datas.First().ContentTypeId,
                    ContentName = datas.First().ContentTypeName,
                    Fields = new Dictionary<ELMField, string>()
                };
                type.Fields = datas.First().ContentFields.ConvertXmlToFieldsWithTemplateAttribute(ObjectContext);
                return type;
            }
            else return null;

        }

        [OperationContract]
        public void UpdateContentTypeFields(Guid TypeId,string TypeName, Dictionary<ELMField, string> fields)
        {
            if (ObjectContext.t_ContentType.Any(c => c.ContentTypeId == TypeId))
            {
                string result = fields.ConvertToXMLDocumentWithTemplateAttribute();
                var ct = ObjectContext.t_ContentType.First(c => c.ContentTypeId == TypeId);
                ct.ContentFields = result;
                ObjectContext.SaveChanges();//先更新模板的xml
                if (TypeId == new Guid("49e9caaa-cc09-412b-87fc-92cc744304cc"))//特殊类型，物料
                {
                    foreach (var matt in ObjectContext.t_Matter)
                    {

                        var ds = matt.Attribute.ConvertXmlToFieldsOnlyValue(ObjectContext);
                        foreach (var field in fields)//遍历模板中的字段，实际数据中不存在模板中的字段则加入
                        {
                            if (!ds.Any(c => c.Key.FieldId == field.Key.FieldId))
                            {
                                ds.Add(field.Key, field.Value);
                            }
                        }
                        if (ds.Count > fields.Count)//如果实际数据中字段大于了模板中的字段则删除，该字段应该是未被使用的字段，在配置模板时都会使用CheckFieldIsInUse来判断是否被使用
                        {
                            var dsIds = ds.Keys.Select(c => c.FieldId);
                            var fieldsIds = fields.Keys.Select(c => c.FieldId);
                            var exps = dsIds.Except(fieldsIds).ToArray();
                            foreach (var item in exps)
                            {
                                ds.Remove(ds.Single(c => c.Key.FieldId == item).Key);
                            }
                        }
                        matt.Attribute = ds.ConvertToXMLDocumentOnlyValue();
                    }
                }
                else if (TypeId == new Guid("293f62fc-e911-4b32-b8b3-b55773efa850"))//特殊类型，用户
                {
                    foreach (var hm in ObjectContext.t_Human.Include("t_Duty"))
                    {

                        var ds = hm.Attribute.ConvertXmlToFieldsOnlyValue(ObjectContext);
                        foreach (var field in fields)
                        {
                            if (!ds.Any(c => c.Key.FieldId == field.Key.FieldId))//实际数据中不存在模板中的字段则加入
                            {
                                ds.Add(field.Key, field.Value);
                            }
                        }
                        if (ds.Count > fields.Count)//如果实际数据中字段大于了模板中的字段则删除，该字段应该是未被使用的字段，在配置模板时都会使用CheckFieldIsInUse来判断是否被使用
                        {
                            var dsIds = ds.Keys.Select(c => c.FieldId);
                            var fieldsIds = fields.Keys.Select(c => c.FieldId);
                            var exps = dsIds.Except(fieldsIds).ToArray();
                            foreach (var item in exps)
                            {
                                ds.Remove(ds.Single(c => c.Key.FieldId == item).Key);
                            }
                        }
                        hm.Attribute = ds.ConvertToXMLDocumentOnlyValue();
                    }
                }
                else//通用数据
                {
                    var query = from q in ObjectContext.t_ELMList.Include("t_ELMItems").Include("t_ContentType") where q.t_ContentType.ContentTypeId == TypeId select q.t_ELMItems;
                    foreach (var items in query)
                    {
                        foreach(var item in items)
                        {
                        var ds = item.DataAttribute.ConvertXmlToFieldsOnlyValue(ObjectContext);
                        foreach (var field in fields)
                        {
                            if (!ds.Any(c => c.Key.FieldId == field.Key.FieldId))//实际数据中不存在模板中的字段则加入
                            {
                                ds.Add(field.Key, field.Value);
                            }
                        }
                        if (ds.Count > fields.Count)//如果实际数据中字段大于了模板中的字段则删除，该字段应该是未被使用的字段，在配置模板时都会使用CheckFieldIsInUse来判断是否被使用
                        {
                            var dsIds = ds.Keys.Select(c => c.FieldId);
                            var fieldsIds = fields.Keys.Select(c => c.FieldId);
                            var exps = dsIds.Except(fieldsIds).ToArray();
                            foreach (var ii in exps)
                            {
                                ds.Remove(ds.Single(c => c.Key.FieldId == ii).Key);
                            }
                        }
                        item.DataAttribute = ds.ConvertToXMLDocumentOnlyValue();
                    }
                    }
                }
                
            }
            else
            {
                t_ContentType ct = new t_ContentType()
                {
                    ContentTypeId=TypeId,
                    ContentTypeName=TypeName,
                    ContentFields=fields.ConvertToXMLDocumentWithTemplateAttribute()

                };
                ObjectContext.AddTot_ContentType(ct);
            }
            ObjectContext.SaveChanges();
        }

        [OperationContract]
        public void UpdateHuman(Human hm)
        {
            var query = (from q in ObjectContext.t_Human where q.Human_ID == hm.HumanId select q).ToList();
            if (query.Count == 1)
            {
                var human = query.First();
                human.Human_Name = hm.HumanName;
                human.Password = hm.Password;
                human.t_Duty = ObjectContext.t_Duty.First(c => c.DutyId == hm.DutyId);
                human.Attribute = hm.Attributes.ConvertToXMLDocumentOnlyValue();
                ObjectContext.SaveChanges();
            }
        }

        [OperationContract]
        public void DelHuman(Human hm)
        {
            var query = (from q in ObjectContext.t_Human where q.Human_ID == hm.HumanId select q).ToList();
            if (query.Count == 1)
            {
                ObjectContext.DeleteObject(query.First());
                ObjectContext.SaveChanges();
            }
        }
        [OperationContract]
        public void DelHumanById(string hmid)
        {
            var query = (from q in ObjectContext.t_Human where q.Human_ID == hmid select q).ToList();
            if (query.Count == 1)
            {
                ObjectContext.DeleteObject(query.First());
                ObjectContext.SaveChanges();
            }
        }
        [OperationContract]
        public void UpdateMatter(Matter mt)
        {
            var query = (from q in ObjectContext.t_Matter where q.Matter_ID == mt.MatterId select q).ToList();
            if (query.Count == 1)
            {
                var matt = query.First();
                matt.Matter_Name = mt.MatterName;
                matt.Attribute = mt.Attributes.ConvertToXMLDocumentOnlyValue();
                ObjectContext.SaveChanges();
            };

        }
        [OperationContract]
        public void DelMatter(Matter mt)
        {
            var query = (from q in ObjectContext.t_Matter where q.Matter_ID == mt.MatterId select q).ToList();
            if (query.Count == 1)
            {
                var matt = query.First();
                ObjectContext.DeleteObject(matt);
                ObjectContext.SaveChanges();
            };

        }
        [OperationContract]
        public void DelMatterById(string mtId)
        {
            var query = (from q in ObjectContext.t_Matter where q.Matter_ID == mtId select q).ToList();
            if (query.Count == 1)
            {
                var matt = query.First();
                ObjectContext.DeleteObject(matt);
                ObjectContext.SaveChanges();
            };

        }

        [OperationContract]
        public bool CheckFieldIsInUse(ELMField field)
        {
            bool bl = false;
            //先判断用户信息
            foreach (var user in ObjectContext.t_Human.Include("t_Duty"))
            {
                var hm = user.ConvertToHuman(ObjectContext);
                if (hm.Attributes.Any(c => c.Key.FieldId == field.FieldId && c.Value != ""))//存在使用了该字段并且有值的用户信息
                {
                    bl = true;
                    break;
                }
            }

            //再判断物料信息
            if (!bl)
            {
                foreach (var matt in ObjectContext.t_Matter)
                {
                    var mt = matt.ConvertToMatter(ObjectContext);
                    if (mt.Attributes.Any(c => c.Key.FieldId == field.FieldId && c.Value != ""))//存在使用了该字段并且有值的物料信息
                    {
                        bl = true;
                        break;
                    }
                }
            }
            return bl;
        }

        [OperationContract]
        public bool CheckFieldIsInContentType(ELMField field)
        {
            bool bl = false;
            var query = from q in ObjectContext.t_ContentType select q;
            foreach (var item in query)
            {
                if (item.ContentFields.ConvertXmlToFieldsOnlyValue(ObjectContext).Any(c => c.Key.FieldId == field.FieldId))
                {
                    bl = true;
                    break;
                }
            }
            return bl;
        }

        [OperationContract]
        public List<ELMField> GetFieldsByGroupId(int groupId)
        {
            return (from q in ObjectContext.t_Field.Include("t_FieldGroup").Include("t_FieldType") where q.IsDeleted == false && q.t_FieldGroup.FieldGroupId == groupId select q).ConvertToFieldTypeList();
        }
        [OperationContract]
        public List<t_FieldGroup> GetAllFieldGroup()
        {
            return (from q in ObjectContext.t_FieldGroup select q).ToList();
        }
        [OperationContract]
        public List<t_FieldType> GetAllFieldType()
        {
            return (from q in ObjectContext.t_FieldType select q).ToList();
        }

        [OperationContract]
        public t_Resource GetRecource(Guid id)
        {
            var query = (from q in ObjectContext.t_Resource where q.ResourceId == id select q).ToList();
            if (query.Count == 1)
            {
                return query.First();
            }
            else
                return null;
        }
        [OperationContract]
        public void  DelELMItem(Guid id)
        {
              var query = (from q in ObjectContext.t_ELMItems where q.ELMItemId == id select q).ToList();
          if(query.Count==1)
               {
                   ELMItem ei = query.First().ConvertToELMItem(ObjectContext);
                   ObjectContext.DeleteObject(ei);
                   ObjectContext.SaveChanges();
          }
        }

        [OperationContract]
        public void UpdateELMItem(ELMItem item)
        {
            var query = (from q in ObjectContext.t_ELMItems where q.ELMItemId == item.ELMItemId select q).ToList();
            if (query.Count == 1)
            {
                var elmitem = query.First();
                elmitem.DataAttribute = item.Datas.ConvertToXMLDocumentOnlyValue();
            }
            else
            {
                ObjectContext.AddTot_ELMItems(item.ConverTot_ELMItem(ObjectContext));
            }
            ObjectContext.SaveChanges();
        }

        [OperationContract]
        public List<ELMItem> GetELMItemsByELMListId(Guid ELMListId)
        {
            
            var query = (from q in ObjectContext.t_ELMItems.Include("t_ELMList") where q.t_ELMList.ID == ELMListId select q).ToList();
            List<ELMItem> ds = new List<ELMItem>();
            foreach (var item in query)
            {
                ELMItem ei = item.ConvertToELMItem(ObjectContext);
                //刷新扩展属性
                var query2 = (from q in ObjectContext.t_ELMList.Include("t_ContentType") where q.ID == ei.ELMList.ELMListId select q).ToList();
                if (query2.Count == 1)
                {
                    var el = query2.First().ConvertToELMList(ObjectContext);
                    ei.ELMList = el;
                    //foreach (var ext in el.ContentType.Fields.Keys)
                    //{
                    //    if (ei.Datas.Any(c => c.Key.FieldId == ext.FieldId))
                    //    {
                    //        var fd = ei.Datas.First(c => c.Key.FieldId == ext.FieldId);
                    //        fd.Key.DisplayMemberGuid = ext.DisplayMemberGuid;
                    //        fd.Key.ItemSourceGuid = ext.ItemSourceGuid;
                    //    }
                    //}
                }
                ds.Add(ei);
            }
            return ds;
        }
        [OperationContract]
        public List<ELMItem> GetAllELMItemsB()
        {
            var query = (from q in ObjectContext.t_ELMItems.Include("t_ELMList") select q).ToList();
            List<ELMItem> ds = new List<ELMItem>();
            foreach (var item in query)
            {
                ELMItem ei = item.ConvertToELMItem(ObjectContext);
                ei.ELMList.ContentType = ObjectContext.t_ELMList.Include("t_ContentType").First(c => c.ID == item.t_ELMList.ID).t_ContentType.ConvertToContentType(ObjectContext);
                ds.Add(ei);
            }
            return ds;
        }
        [OperationContract]
        public ELMItem GetELMItemById(Guid itemId)
        {
            var query = (from q in ObjectContext.t_ELMItems.Include("t_ELMList") where q.ELMItemId == itemId select q).ToList();
          if(query.Count==1)
               {
                   ELMItem ei = query.First().ConvertToELMItem(ObjectContext);
                   //刷新扩展属性
                   var query2 = (from q in ObjectContext.t_ELMList.Include("t_ContentType") where q.ID == ei.ELMList.ELMListId select q).ToList();
                   if (query2.Count == 1)
                   {
                       var el = query2.First().ConvertToELMList(ObjectContext);
                       ei.ELMList = el;
                       foreach (var ext in el.ContentType.Fields.Keys)
                       {
                           if (ei.Datas.Any(c => c.Key.FieldId == ext.FieldId))
                           {
                               var fd = ei.Datas.First(c => c.Key.FieldId == ext.FieldId);
                               fd.Key.DisplayMemberGuid = ext.DisplayMemberGuid;
                               fd.Key.ItemSourceGuid = ext.ItemSourceGuid;
                           }
                       }
                   }
                   return ei;   
            }
            else
            return null;
        }
        [OperationContract]
        public void UpdateELMList(ELMList elmList)
        {
            if (ObjectContext.t_ELMList.Any(c => c.ID == elmList.ELMListId))
            {
                var data = ObjectContext.t_ELMList.Include("t_ContentType").First(c => c.ID == elmList.ELMListId);
                data.ELMListName = elmList.ELMListName;
            }
            else
            {
                t_ELMList dd = elmList.ConverTot_ELMList(ObjectContext);
                ObjectContext.AddTot_ELMList(dd);
            }
            ObjectContext.SaveChanges();
        }

        [OperationContract]
        public List<ELMList> GetAllELMLists()
        {
            var query = (from q in ObjectContext.t_ELMList.Include("t_ELMItems").Include("t_ContentType") select q).ToList();
            List<ELMList> ds = new List<ELMList>();
            foreach (var item in query)
            {
                ELMList ei = item.ConvertToELMList(ObjectContext);
                ds.Add(ei);
            }
            return ds;
        }
        [OperationContract]
        public ELMList GetELMListByELMListId(Guid ELMListId)
        {
            var query = (from q in ObjectContext.t_ELMList.Include("t_ELMItems") where q.ID == ELMListId select q).ToList();
           if(query.Count==1)
            {
                ELMList ei = query.First().ConvertToELMList(ObjectContext);
                return ei;
            }
            else
            return null;
        }

        private object[] CreateItemsSource(DataTable dt)
        {
            Type _RowClass;
            AssemblyName an = new AssemblyName("Result" + this.GetHashCode());
            System.Reflection.Emit.AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
            TypeBuilder tb = moduleBuilder.DefineType("RowType" + this.GetHashCode(), TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, typeof(object)); ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
            IEnumerator columns = dt.Columns.GetEnumerator();
            while (columns.MoveNext())
            {
                DataColumn info = (DataColumn)columns.Current; FieldBuilder field = tb.DefineField(info.ColumnName.Replace(' ', '_'), info.DataType, FieldAttributes.Private);
                PropertyBuilder propBldr = tb.DefineProperty(info.ColumnName.Replace(' ', '_'), System.Reflection.PropertyAttributes.HasDefault, info.DataType, new Type[] { info.DataType });
                MethodAttributes getSetAttr = MethodAttributes.Public;
                MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + info.ColumnName, getSetAttr, info.DataType, new Type[] { });
                ILGenerator custNameGetIL = getPropMthdBldr.GetILGenerator();
                custNameGetIL.Emit(OpCodes.Ldarg_0);
                custNameGetIL.Emit(OpCodes.Ldfld, field);
                custNameGetIL.Emit(OpCodes.Ret);
                MethodBuilder setPropMthdBldr = tb.DefineMethod("set_" + info.ColumnName, getSetAttr, null, new Type[] { info.DataType });
                ILGenerator custNameSetIL = setPropMthdBldr.GetILGenerator();
                custNameSetIL.Emit(OpCodes.Ldarg_0); custNameSetIL.Emit(OpCodes.Ldarg_1); custNameSetIL.Emit(OpCodes.Stfld, field);
                custNameSetIL.Emit(OpCodes.Ret);
                propBldr.SetGetMethod(getPropMthdBldr);
                propBldr.SetSetMethod(setPropMthdBldr);
            }
            _RowClass = tb.CreateType();
            object[] itemsSource = new object[dt.Rows.Count];
            for (int rowIdx = 0; rowIdx < dt.Rows.Count; rowIdx++)
            {
                object row = Activator.CreateInstance(_RowClass); columns = dt.Columns.GetEnumerator();
                int i = 0;
                while (columns.MoveNext())
                {
                    DataColumn info = (DataColumn)columns.Current;
                    PropertyInfo field = _RowClass.GetProperty(info.ColumnName.Replace(' ', '_'));
                    object val = dt.Rows[rowIdx][i++];
                    field.SetValue(row, Convert.ChangeType(val, field.PropertyType), null);
                }
                itemsSource[rowIdx] = row;
            }
            return itemsSource;
        }

         


    }
}
